﻿using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;

namespace System.Modules.Utility.DTO.ULS.Searching
{
    class OverflowCollection<T> : ObservableCollection<T>
    {
        #region Fields
        readonly Func<T, bool> _evictionCriterea;
        bool _deferNotification;
        #endregion

        #region Properties
        public int MaxItems { get; set; }
        #endregion

        #region Constructors
        public OverflowCollection(Func<T, bool> evictionCriterea)
        {
            _evictionCriterea = evictionCriterea;
        }

        public OverflowCollection(IEnumerable<T> collection) : base(collection) { }
        #endregion

        #region Methods
        public void AddRange(IEnumerable<T> collection)
        {
            _deferNotification = true;
            foreach (var item in collection) Add(item);
            _deferNotification = false;
            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
        }

        protected override void InsertItem(int index, T item)
        {
            if (MaxItems > 0 && Count == MaxItems)
            {
                var removeItem = Items.FirstOrDefault(target => _evictionCriterea(target));
                if (removeItem != null)
                {
                    Remove(removeItem);
                }
            }
            base.InsertItem(index, item);
        }

        protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            if (!_deferNotification) base.OnCollectionChanged(e);
        }
        #endregion
    }
}
